#pragma once
#include <unordered_map>
#include <sstream>
#include "util.hpp"

namespace cloud
{
	class DataManager
	{
	private:
		string _backup_file;
		unordered_map<string, string> _table;
	public:
		DataManager(const string& backup_file):_backup_file(backup_file){
			InitLoad();
		}
		bool Storage()
		{
			std::stringstream ss;
			auto it = _table.begin();
			while (it != _table.end())
			{
				ss << it->first << " " << it->second << endl;
				it++;
			}
			Util::FileUtil fu(_backup_file);
			fu.SetContent(ss.str());
			return true;
		}
		int Split(const string& str, const string& sep, vector<string>* arr)
		{
			int count = 0;
			size_t pos = 0, idx = 0;
			while (true)
			{
				pos = str.find(sep, idx);
				if (pos == string::npos)
				{
					break;
				}
				if (pos == idx)
				{
					idx = pos + sep.size();
					continue;
				}
				string tem = str.substr(idx, pos - idx);
				arr->push_back(tem);
				count++;
				idx = pos + sep.size();
			}
			if (idx < str.size()) {
				arr->push_back(str.substr(idx));
				count++;
			}
			return count;
		}
		bool InitLoad()
		{
			Util::FileUtil fu(_backup_file);
			string body;
			fu.GetContent(&body);

			vector<string> arr;
			Split(body, "\n", &arr);
			for (auto& a : arr)
			{
				vector<string> tem;
				Split(a, " ", &tem);
				if (tem.size() != 2)continue;
				_table[tem[0]] = tem[1];
			}
			return true;
		}
		bool Insert(const string& key, const string& val)
		{
			_table[key] = val;
			Storage();
			return true;
		}
		bool Update(const string& key, const string& val)
		{
			_table[key] = val;
			Storage();
			return true;
		}
		bool GetOneKey(const string& key, string* val)
		{
			auto it = _table.find(key);
			if (it == _table.end())
			{
				return false;
			}
			*val = it->second;
			return true;
		}
	};
}